home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP11.ZIP / CHAP11 / POLYLINE / IVIEWOBJ.CPP < prev    next >
C/C++ Source or Header  |  1993-06-22  |  10KB  |  358 lines

  1. /*
  2.  * IVIEWOBJ.CPP
  3.  * Polyline Component Object Chapter 11
  4.  *
  5.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  6.  *
  7.  * Kraig Brockschmidt, Software Design Engineer
  8.  * Microsoft Systems Developer Relations
  9.  *
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #include "polyline.h"
  16.  
  17.  
  18. /*
  19.  * CImpIViewObject::CImpIViewObject
  20.  * CImpIViewObject::~CImpIViewObject
  21.  *
  22.  * Parameters (Constructor):
  23.  *  pObj            LPCPolyline of the object we're in.
  24.  *  punkOuter       LPUNKNOWN to which we delegate.
  25.  */
  26.  
  27. CImpIViewObject::CImpIViewObject(LPCPolyline pObj, LPUNKNOWN punkOuter)
  28.     {
  29.     m_cRef=0;
  30.     m_pObj=pObj;
  31.     m_punkOuter=punkOuter;
  32.     return;
  33.     }
  34.  
  35. CImpIViewObject::~CImpIViewObject(void)
  36.     {
  37.     return;
  38.     }
  39.  
  40.  
  41.  
  42.  
  43. /*
  44.  * CImpIViewObject::QueryInterface
  45.  * CImpIViewObject::AddRef
  46.  * CImpIViewObject::Release
  47.  *
  48.  * Purpose:
  49.  *  IUnknown members for CImpIViewObject object.
  50.  */
  51.  
  52. STDMETHODIMP CImpIViewObject::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  53.     {
  54.     return m_punkOuter->QueryInterface(riid, ppv);
  55.     }
  56.  
  57.  
  58. STDMETHODIMP_(ULONG) CImpIViewObject::AddRef(void)
  59.     {
  60.     ++m_cRef;
  61.     return m_punkOuter->AddRef();
  62.     }
  63.  
  64. STDMETHODIMP_(ULONG) CImpIViewObject::Release(void)
  65.     {
  66.     --m_cRef;
  67.     return m_punkOuter->Release();
  68.     }
  69.  
  70.  
  71.  
  72. /*
  73.  * CImpIViewObject::Draw
  74.  *
  75.  * Purpose:
  76.  *  Draws the object on the given hDC specifically for the requested
  77.  *  aspect, device, and within the appropriate bounds.
  78.  *
  79.  * Parameters:
  80.  *  dwAspect        DWORD aspect to draw.
  81.  *  lindex          LONG index of the piece to draw.
  82.  *  pvAspect        LPVOID for extra information, always NULL.
  83.  *  ptd             DVTARGETDEVICE FAR * containing device information.
  84.  *  hICDev          HDC containing the IC for the device.
  85.  *  hDC             HDC on which to draw.
  86.  *  pRectBounds     LPRECTL describing the rectangle in which to draw.
  87.  *  pRectWBounds    LPRECTL describing the placement rectangle if part
  88.  *                  of what you draw is another metafile.
  89.  *  pfnContinue     Function to call periodically during long repaints.
  90.  *  dwContinue      DWORD extra information to pass to the pfnContinue.
  91.  *
  92.  * Return Value:
  93.  *  HRESULT         NOERROR on success, error code otherwise.
  94.  */
  95.  
  96. STDMETHODIMP CImpIViewObject::Draw(DWORD dwAspect, LONG lindex
  97.     , void FAR * pvAspect, DVTARGETDEVICE FAR * ptd, HDC hICDev
  98.     , HDC hDC, const LPRECTL pRectBounds, const LPRECTL pRectWBounds
  99.     , BOOL (CALLBACK * pfnContinue) (DWORD), DWORD dwContinue)
  100.     {
  101.     RECT            rc;
  102.     POLYLINEDATA    pl;
  103.     LPPOLYLINEDATA  ppl=&m_pObj->m_pl;
  104.  
  105.     RECTFROMRECTL(rc, *pRectBounds);
  106.  
  107.     //Delegate iconic and printed representations.
  108.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  109.         {
  110.         return m_pObj->m_pDefIViewObject->Draw(dwAspect, lindex
  111.             , pvAspect, ptd, hICDev, hDC, pRectBounds, pRectWBounds
  112.             , pfnContinue, dwContinue);
  113.         }
  114.  
  115.  
  116.     /*
  117.      * If we're asked to draw a frozen aspect, use the data from
  118.      * a copy we made in IViewObject::Freeze.  Otherwise use the
  119.      * current data.
  120.      */
  121.     if (dwAspect & m_pObj->m_dwFrozenAspects)
  122.         {
  123.         //Point to the data to actually use.
  124.         if (DVASPECT_CONTENT==dwAspect)
  125.             ppl=&m_pObj->m_plContent;
  126.         else
  127.             ppl=&m_pObj->m_plThumbnail;
  128.         }
  129.  
  130.  
  131.     //Make a copy so we can modify it (and not worry about threads)
  132.     _fmemcpy(&pl, ppl, CBPOLYLINEDATA);
  133.  
  134.     /*
  135.      * If we're going to a printer, check if it's color capable.
  136.      * if not, then use black on white for this figure.
  137.      */
  138.     if (NULL!=hICDev)
  139.         {
  140.         if (GetDeviceCaps(hICDev, NUMCOLORS) <= 2)
  141.             {
  142.             pl.rgbBackground=RGB(255, 255, 255);
  143.             pl.rgbLine=RGB(0, 0, 0);
  144.             }
  145.         }
  146.  
  147.     m_pObj->Draw(hDC, FALSE, TRUE, &rc, &pl);
  148.     return NOERROR;
  149.     }
  150.  
  151.  
  152.  
  153.  
  154. /*
  155.  * CImpIViewObject::GetColorSet
  156.  *
  157.  * Purpose:
  158.  *
  159.  * Parameters:
  160.  *  dwAspect        DWORD aspect of interest.
  161.  *  lindex          LONG piece of interest.
  162.  *  pvAspect        LPVOID containing extra information, always NULL.
  163.  *  ptd             DVTARGETDEVICE FAR * containing device information.
  164.  *  hICDev          HDC containing the IC for the device.
  165.  *  ppColorSet      LPLOGPALETTE FAR * into which to return the pointer
  166.  *                  to the palette in this color set.
  167.  *
  168.  * Return Value:
  169.  *  HRESULT         NOERROR on success, S_FALSE if not supported.
  170.  */
  171.  
  172. STDMETHODIMP CImpIViewObject::GetColorSet(DWORD dwDrawAspect, LONG lindex
  173.     , LPVOID pvAspect, DVTARGETDEVICE FAR * ptd
  174.     , HDC hICDev, LPLOGPALETTE FAR * ppColorSet)
  175.     {
  176.     return ResultFromScode(S_FALSE);
  177.     }
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184. /*
  185.  * CImpIViewObject::Freeze
  186.  *
  187.  * Purpose:
  188.  *  Freezes the view of a particular aspect such that data changes do
  189.  *  no affect the view.
  190.  *
  191.  * Parameters:
  192.  *  dwAspect        DWORD aspect to freeze.
  193.  *  lindex          LONG piece index under consideration.
  194.  *  pvAspect        LPVOID for further information, always NULL.
  195.  *  pdwFreeze       LPDWORD in which to return the key.
  196.  *
  197.  * Return Value:
  198.  *  HRESULT         NOERROR on success, error code otherwise.
  199.  */
  200.  
  201. STDMETHODIMP CImpIViewObject::Freeze(DWORD dwAspect, LONG lindex
  202.     , LPVOID pvAspect, LPDWORD pdwFreeze)
  203.     {
  204.     //Delegate anything for ICON or DOCPRINT aspects
  205.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  206.         {
  207.         return m_pObj->m_pDefIViewObject->Freeze(dwAspect, lindex
  208.             , pvAspect, pdwFreeze);
  209.         }
  210.  
  211.     if (dwAspect & m_pObj->m_dwFrozenAspects)
  212.         {
  213.         *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  214.         return ResultFromScode(VIEW_S_ALREADY_FROZEN);
  215.         }
  216.  
  217.     m_pObj->m_dwFrozenAspects |= dwAspect;
  218.  
  219.  
  220.     /*
  221.      * For whatever aspects become frozen, make a copy of the data.
  222.      * Later when drawing, if such a frozen aspect is requested, we'll
  223.      * draw from this data rather than from our current data.
  224.      */
  225.     if (DVASPECT_CONTENT & dwAspect)
  226.         _fmemcpy(&m_pObj->m_plContent, &m_pObj->m_pl, CBPOLYLINEDATA);
  227.  
  228.     if (DVASPECT_THUMBNAIL & dwAspect)
  229.         _fmemcpy(&m_pObj->m_plThumbnail, &m_pObj->m_pl, CBPOLYLINEDATA);
  230.  
  231.     if (NULL!=pdwFreeze)
  232.         *pdwFreeze=dwAspect + FREEZE_KEY_OFFSET;
  233.  
  234.     return NOERROR;
  235.     }
  236.  
  237.  
  238.  
  239.  
  240.  
  241.  
  242. /*
  243.  * CImpIViewObject::Unfreeze
  244.  *
  245.  * Purpose:
  246.  *  Thaws an aspect frozen in ::Freeze.  We expect that a container
  247.  *  will redraw us after freezing if necessary, so we don't send
  248.  *  any sort of notification here.
  249.  *
  250.  * Parameters:
  251.  *  dwFreeze        DWORD key returned from ::Freeze.
  252.  *
  253.  * Return Value:
  254.  *  HRESULT         NOERROR on success, error code otherwise.
  255.  */
  256.  
  257. STDMETHODIMP CImpIViewObject::Unfreeze(DWORD dwFreeze)
  258.     {
  259.     DWORD       dwAspect=dwFreeze - FREEZE_KEY_OFFSET;
  260.  
  261.     //Delegate anything for ICON or DOCPRINT aspects
  262.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspect))
  263.         m_pObj->m_pDefIViewObject->Unfreeze(dwFreeze);
  264.  
  265.     //The aspect to unfreeze is in the key.
  266.     m_pObj->m_dwFrozenAspects &= ~(dwAspect);
  267.  
  268.     /*
  269.      * Since we always kept our current data up to date, we don't
  270.      * have to do anything thing here like requesting data again.
  271.      * Because we removed dwAspect from m_dwFrozenAspects, Draw
  272.      * will again use the current data.
  273.      */
  274.  
  275.     return NOERROR;
  276.     }
  277.  
  278.  
  279.  
  280.  
  281.  
  282. /*
  283.  * CImpIViewObject::SetAdvise
  284.  *
  285.  * Purpose:
  286.  *  Provides an advise sink to the view object enabling notifications
  287.  *  for a specific aspect.
  288.  *
  289.  * Parameters:
  290.  *  dwAspects       DWORD describing the aspects of interest.
  291.  *  dwAdvf          DWORD containing advise flags.
  292.  *  pIAdviseSink    LPADVISESINK to notify.
  293.  *
  294.  * Return Value:
  295.  *  HRESULT         NOERROR on success, error code otherwise.
  296.  */
  297.  
  298. STDMETHODIMP CImpIViewObject::SetAdvise(DWORD dwAspects, DWORD dwAdvf
  299.     , LPADVISESINK pIAdviseSink)
  300.     {
  301.     //Pass anything with DVASPECT_ICON or _DOCPRINT to the handler.
  302.     if (!((DVASPECT_CONTENT | DVASPECT_THUMBNAIL) & dwAspects))
  303.         m_pObj->m_pDefIViewObject->SetAdvise(dwAspects, dwAdvf, pIAdviseSink);
  304.  
  305.     //We continue because dwAspects may have more than one in it.
  306.     if (NULL!=m_pObj->m_pIAdviseSink)
  307.         m_pObj->m_pIAdviseSink->Release();
  308.  
  309.     m_pObj->m_dwAdviseAspects=dwAspects;
  310.     m_pObj->m_dwAdviseFlags=dwAdvf;
  311.  
  312.     if (NULL!=pIAdviseSink)
  313.         {
  314.         m_pObj->m_pIAdviseSink=pIAdviseSink;
  315.         m_pObj->m_pIAdviseSink->AddRef();
  316.         }
  317.  
  318.     return NOERROR;
  319.     }
  320.  
  321.  
  322.  
  323.  
  324. /*
  325.  * CImpIViewObject::GetAdvise
  326.  *
  327.  * Purpose:
  328.  *  Returns the last known IAdviseSink seen by ::SetAdvise.
  329.  *
  330.  * Parameters:
  331.  *  pdwAspects      LPDWORD in which to store the last requested aspects.
  332.  *  pdwAdvf         LPDWORD in which to store the last requested flags.
  333.  *  ppIAdvSink      LPADVISESINK FAR * in which to store the IAdviseSink.
  334.  *
  335.  * Return Value:
  336.  *  HRESULT         NOERROR on success, error code otherwise.
  337.  */
  338.  
  339. STDMETHODIMP CImpIViewObject::GetAdvise(LPDWORD pdwAspects
  340.     , LPDWORD pdwAdvf, LPADVISESINK FAR* ppAdvSink)
  341.     {
  342.     if (NULL==ppAdvSink)
  343.         return ResultFromScode(E_INVALIDARG);
  344.     else
  345.         {
  346.         *ppAdvSink=m_pObj->m_pIAdviseSink;
  347.         m_pObj->m_pIAdviseSink->AddRef();
  348.         }
  349.  
  350.     if (NULL!=pdwAspects)
  351.         *pdwAspects=m_pObj->m_dwAdviseAspects;
  352.  
  353.     if (NULL!=pdwAdvf)
  354.         *pdwAdvf=m_pObj->m_dwAdviseFlags;
  355.  
  356.     return NOERROR;
  357.     }
  358.